package cn.conac.as.monitor.service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;

import cn.conac.as.framework.service.GenericService;
import cn.conac.as.monitor.constant.AllowSend;
import cn.conac.as.monitor.constant.HttpMethodType;
import cn.conac.as.monitor.constant.ScanResultType;
import cn.conac.as.monitor.entity.BdtEmailEntity;
import cn.conac.as.monitor.entity.BdtInterfaceEntity;
import cn.conac.as.monitor.entity.BdtInterfaceMonitorEntity;
import cn.conac.as.monitor.entity.BdtVSystemInterfaceMonitorEntity;
import cn.conac.as.monitor.entity.weixin.TemplateData;
import cn.conac.as.monitor.entity.weixin.WxinTemplate;
import cn.conac.as.monitor.repository.BdtEmailRepository;
import cn.conac.as.monitor.repository.BdtInterfaceMonitorRepository;
import cn.conac.as.monitor.repository.BdtInterfaceRepository;
import cn.conac.as.monitor.repository.BdtVSystemInterfaceMonitorRepository;
import cn.conac.as.monitor.util.HttpClientUtil;
import cn.conac.as.monitor.util.PropertiesUtil;

/**
 * 接口监控服务类
 * @author lishen
 * @date	2017年7月7日上午10:42:09
 * @version 1.0
 */
@Service
//@Component
public class BdtInterfaceMonitorService extends GenericService<BdtInterfaceMonitorEntity, String> {
	@Autowired
    private BdtInterfaceMonitorRepository imRepository;
	
	@Autowired
	private BdtInterfaceRepository iRepository;
	
	@Autowired
	private BdtEmailRepository bdtEmailRepository;
	
	@Autowired
	private BdtVSystemInterfaceMonitorRepository bdtVSystemInterfaceMonitorRepository;
	
	@Autowired
    private EmailService emailService;
	
	@Autowired
    private WeixinService weixinService;
	
	/**
	 * 是否发送微信提醒
	 */
	private static final boolean SEND_EMAIL_WARNING = Boolean.parseBoolean(PropertiesUtil.getValue("config/config.properties", "send.email.warning"));
	
	/**
	 * 是否发送微信提醒
	 */
	private static final boolean SEND_WECHAT_WARNING = Boolean.parseBoolean(PropertiesUtil.getValue("config/config.properties", "send.weChat.warning"));
	
	/**
	 * 模拟登录的url
	 */
	private static final String AUTH_URL = PropertiesUtil.getValue("config/config.properties", "auth.url");
	
	/**
	 * 模拟登录的账号/密码
	 */
	private static final String AUTH_USERNAME_PASSWORD = PropertiesUtil.getValue("config/config.properties", "auth.username.password");
	
	/**
	 * 生产环境登录时使用的token
	 */
	private static final String PROD_ENV_LOGIN_TOKEN = PropertiesUtil.getValue("config/config.properties", "prod.env.login.token");

	/**
	 * 以后台服务方式运行，每隔一段时间对每一个接口进行测试
	 */
	public void startTimingMonitor() {
		BdtInterfaceMonitorEntity imEntity=null;
		// 获取接口表中的所有记录
		List<BdtInterfaceEntity> interfaceList=iRepository.findAll();
		
		// 当接口表中没有数据时，直接返回
		if(null==interfaceList || interfaceList.size()==0){
			logger.info("接口表 BDT_INTERFACE中没有数据！");
		}
		
		// 登录验证
		auth();
		// 获取新的token
		String newToken=this.refreshToken();
		
		for(int i=0; i<interfaceList.size(); i++){
			BdtInterfaceEntity bdtInterfaceEntity=interfaceList.get(i);
			if(null!=bdtInterfaceEntity){
				// POST方法
				if(bdtInterfaceEntity.getMethod().equals(HttpMethodType.POST)){
					if(null!=bdtInterfaceEntity.getParameterUseCase()){
//						Map<String, String> param=FastJsonUtil.jsonToMap(bdtInterfaceEntity.getParameterUseCase());
						imEntity=HttpClientUtil.post(bdtInterfaceEntity, bdtInterfaceEntity.getParameterUseCase(), newToken);
					}else{
						imEntity=HttpClientUtil.post(bdtInterfaceEntity, null, newToken);
					}
					logger.info(imEntity!=null?imEntity.toString():"接口(id: "+bdtInterfaceEntity.getId()+") 为null");
					if(null!=imEntity){
						imRepository.save(imEntity);
					}
				}
				// GET方法
				if(bdtInterfaceEntity.getMethod().equals(HttpMethodType.GET)){
					imEntity=HttpClientUtil.get(bdtInterfaceEntity, newToken);
					if(null!=imEntity){
						imRepository.save(imEntity);
					}
				}
				try{
				// 当接口监控的结果为警告或不可用时，发送邮件
				if(SEND_EMAIL_WARNING){
					if(null!=imEntity && (imEntity.getScanResult().equals(ScanResultType.WARNING) || imEntity.getScanResult().equals(ScanResultType.DISABLE))){
						// 获取所有需要接收到邮件的邮箱
						List<BdtEmailEntity> bdtEmailEntityList=bdtEmailRepository.findAll();
						if(null!=bdtEmailEntityList && bdtEmailEntityList.size()>0){
							for(int j=0; j<bdtEmailEntityList.size() && bdtEmailEntityList.get(j).getAllowSend().equals(AllowSend.ALLOW_SEND); j++){
								BdtEmailEntity bdtEmailEntity=bdtEmailEntityList.get(j);
								BdtVSystemInterfaceMonitorEntity bdtVSystemInterfaceMonitorEntity=bdtVSystemInterfaceMonitorRepository.findByIdAndInterfaceId(imEntity.getId(), imEntity.getInterfaceId());
								emailService.sendTemplateMail(bdtEmailEntity.getAddress(), bdtVSystemInterfaceMonitorEntity);
							}
						}
					}
				}}catch(Exception e){
					e.printStackTrace();
				}
				
				// 当接口监控的结果为警告或不可用时，发送微信消息
				if(SEND_WECHAT_WARNING){
					if(null!=imEntity && (imEntity.getScanResult().equals(ScanResultType.WARNING) || imEntity.getScanResult().equals(ScanResultType.DISABLE))){
						// 获取所有需要接收到微信消息的用户
						List<String> openIdList=weixinService.getUserOpenId();
						if(null!=openIdList && openIdList.size()!=0){
								BdtVSystemInterfaceMonitorEntity bdtVSystemInterfaceMonitorEntity=bdtVSystemInterfaceMonitorRepository.findByIdAndInterfaceId(imEntity.getId(), imEntity.getInterfaceId());
							for(int j=0; j<openIdList.size(); j++){
								WxinTemplate tm  = new WxinTemplate();
						        tm.setTouser(openIdList.get(j).toString());
						        tm.setTemplate_id("QOqUUK5drSS8NXD9n8fndxoMmvEWxBCzzIxVqgE6J94");
						        tm.setTopcolor("#ff0000");
						        tm.setUrl("http://jgbzy.conac.cn");
						        Map<String ,Object> data = new HashMap<String,Object>();
						        data.put("path",new TemplateData(bdtInterfaceEntity.getUrl(),"#00ff00"));
						        data.put("description",new TemplateData(bdtVSystemInterfaceMonitorEntity.getDescription(),"#00ff00"));
						        data.put("responseTime",new TemplateData(bdtVSystemInterfaceMonitorEntity.getResponseTime(),"#00ff00"));
						        data.put("scanResult",new TemplateData(bdtVSystemInterfaceMonitorEntity.getScanResult(),"#00ff00"));
						        data.put("errorInfo",new TemplateData(bdtVSystemInterfaceMonitorEntity.getErrorInfo(),"#00ff00"));
						        tm.setData(data);

						        WeixinService.postTemplateMsg(tm);
							}
						}
					}
				}
			}
		}
	}

	/**
	 * 登录验证
	 */
	private void auth() {
		logger.info("测试之前的模拟登录验证开始...");
		
		CloseableHttpClient httpclient = null;
		CloseableHttpResponse response = null;
		HttpPost httpPost = null;
		try {
			HttpContext httpContext = new BasicHttpContext();
			RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(10000).build();
			httpclient = HttpClients.createDefault();
			httpPost = new HttpPost(AUTH_URL);
			// 如果没有这个设置，汇报"error":"Unsupported Media Type"
			httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
			httpPost.setConfig(defaultRequestConfig);
			StringEntity strEntity = new StringEntity(AUTH_USERNAME_PASSWORD);
			httpPost.setEntity(strEntity);
			response = httpclient.execute(httpPost, httpContext);
			HttpHost currentHost = (HttpHost) httpContext.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
			HttpUriRequest req = (HttpUriRequest) httpContext.getAttribute(ExecutionContext.HTTP_REQUEST);
			logger.debug((req.getURI().isAbsolute()) ? req.getURI().toString() : (currentHost.toURI() + req.getURI()));

			HttpEntity entity = response.getEntity();
			String result = EntityUtils.toString(entity);
			logger.debug("测试的返回值： " + result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 刷新token
	 * @return
	 */
	private String refreshToken(){
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost("http://jgbzy.conac.cn/api/auth/refresh");
		// 如果没有这个设置，汇报"error":"Unsupported Media Type"
		httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
		// 在header里存储token，否则没有权限
		httpPost.setHeader("Authorization", PROD_ENV_LOGIN_TOKEN);

		try {
			CloseableHttpResponse response = httpClient.execute(httpPost);

			HttpEntity entity = response.getEntity();
			String result = EntityUtils.toString(entity);
			JSONObject obj=JSON.parseObject(result);
			return obj.getString("result");

		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 关闭连接,释放资源
			try {
				httpClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

}
